#pragma once

#include "sys/ptr.h"
#include "IConnection.h"
#include "IDataEntity.h"

SYS_BEGIN()
template<typename IF_Type>
class DataInterfacePtr : public InterfacePtr<IF_Type>
{
	typedef DataInterfacePtr<IF_Type> thisClass;
public:
	DataInterfacePtr(IF_Type* pInterface=NULL):
	  InterfacePtr(pInterface)
	  {
		  if(m_pInterface)
			  m_pInterface->IncInterfaceRef();
	  }
	  template<typename TOtherInterface>
	  explicit DataInterfacePtr(const InterfacePtr<TOtherInterface>& pInterface)
		  :InterfacePtr(pInterface)
	  {
	  }
	  explicit DataInterfacePtr(const thisClass& o) :
	  InterfacePtr(o.m_pInterface)
	  {
	  }
	  explicit DataInterfacePtr(const ObjectPtr& pObject) :
	  InterfacePtr(pObject)
	  {
	  }
	  explicit DataInterfacePtr(IObject* pObject) :
	  InterfacePtr(pObject)
	  {
	  }

	  explicit DataInterfacePtr(IConnection* connection,objectid oid) :
	  InterfacePtr((IF_Type*)NULL)
	  {
		  IInterface* pIF=NULL;
		  if(connection->QueryVInterface(oid,IID_IF,&pIF)==vok)
		  {
			  ASSERT(pIF!=NULL);
			  m_pInterface=static_cast<IF_Type*>(pIF);
		  }
	  }

	  vresult QueryVInterface(IConnection* connection,objectid oid)
	  {
		  ASSERT(connection!=NULL);
		  ASSERT(oid>=OBJID_ROOT);
		  IInterface* pIF=NULL;
		  vresult vr=connection->QueryVInterface(oid,IID_IF,&pIF);
		  if(vr!=vok)
			  return vr;
		  ASSERT(pIF!=NULL);
		  if(pIF==static_cast<IInterface*>(m_pInterface))
		  {
			  pIF->DecInterfaceRef();
			  return vok;
		  }
		  Unload();
		  m_pInterface=static_cast<IF_Type*>(pIF);
		  return vok;
	  }
};
SYS_END()